using System;
using System.Collections.Generic;
using System.Text;
using THSLib;
using THSERP.BusinessEntities;
namespace THSERP.BaseProvider
{
    public class TransactionUtil
    {
        
        public enum InventoryStatus {Empty = 1, LessThanMinQty = 2, GreaterThanMaxQty = 3, Valid = 4};
        
        public enum InventoryType { OnHand = 1, SaleOrder = 2, PurchaseOrder = 3, Proposal = 4 };
        
        #region Constant
        public const string cstInventoryShipment = "Shipment";
        public const string cstInventoryProposal = "Proposal";
        public const string cstInventorySaleOrder = "SaleOrder";
        public const string cstInventoryPurchaseOrder = "PurchaseOrder";
        public const string cstInventoryReceipt = "Receipt";
        
        public const string cstInventoryAdjust = "Adjustment";
        #endregion

        #region Update Inventory functions
        public static int UpdateInventoryStock(int iICProductID, int iICStockID,
                                        double dbProductQuantity, String strUpdateType)
        {
            int iICInventoryStockID = 0;
            ICInventoryStocksController objICInventoryStocksController = new ICInventoryStocksController();
            ICInventoryStocksInfo objICInventoryStocksInfo = objICInventoryStocksController.GetInventoryStockByProductAndStock(iICProductID, iICStockID);
            if (objICInventoryStocksInfo != null)
            {
                UpdateInventoryStockQuantity(
                    objICInventoryStocksInfo, 
                    dbProductQuantity,                     
                    strUpdateType);
                iICInventoryStockID = objICInventoryStocksController.UpdateObject(objICInventoryStocksInfo);
            }
            else
            {
                objICInventoryStocksInfo = new ICInventoryStocksInfo();
                objICInventoryStocksInfo.FK_ICStockID = iICStockID;
                objICInventoryStocksInfo.FK_ICProductID = iICProductID;
                UpdateInventoryStockQuantity(
                    objICInventoryStocksInfo,
                    dbProductQuantity,                    
                    strUpdateType);

                iICInventoryStockID = objICInventoryStocksController.CreateObject(objICInventoryStocksInfo);
            }

            return iICInventoryStockID;
        }

        public static int UpdateInventoryStock(int iICProductID, int iICProductAttributeID, int iICStockID,
                                        double dbProductQuantity, String strUpdateType)
        {
            int iICInventoryStockID = 0;
            ICInventoryStocksController objICInventoryStocksController = new ICInventoryStocksController();
            ICInventoryStocksInfo objICInventoryStocksInfo = objICInventoryStocksController.GetInventoryStockByStockIDAndProductIDAndProductAttributeID(iICStockID, iICProductID, iICProductAttributeID);
            if (objICInventoryStocksInfo != null)
            {
                UpdateInventoryStockQuantity(
                    objICInventoryStocksInfo,
                    dbProductQuantity,
                    strUpdateType);
                iICInventoryStockID = objICInventoryStocksController.UpdateObject(objICInventoryStocksInfo);
            }
            else
            {
                objICInventoryStocksInfo = new ICInventoryStocksInfo();
                objICInventoryStocksInfo.FK_ICStockID = iICStockID;
                objICInventoryStocksInfo.FK_ICProductID = iICProductID;
                objICInventoryStocksInfo.FK_ICProductAttributeID = iICProductAttributeID;
                UpdateInventoryStockQuantity(
                    objICInventoryStocksInfo,
                    dbProductQuantity,
                    strUpdateType);

                iICInventoryStockID = objICInventoryStocksController.CreateObject(objICInventoryStocksInfo);
            }

            return iICInventoryStockID;
        }

        public static int UpdateInventoryStockSerials(int iICInventoryStockID, int iICProductID,
                                            int iICStockID,String strICProductSerialNo,
                                            double dbProductQuantity,
                                            String strUpdateType)
        {
            int iICInventoryStockSerialID = 0;
            ICInventoryStockSerialsController objICInventoryStockSerialsController = new ICInventoryStockSerialsController();
            ICInventoryStockSerialsInfo objICInventoryStockSerialsInfo = objICInventoryStockSerialsController.GetInventoryStockSerialByProductAndProductSerialNoAndStock(iICProductID,strICProductSerialNo, iICStockID);
            if (objICInventoryStockSerialsInfo != null)
            {
                UpdateInventoryStockSerialQuantity(
                    objICInventoryStockSerialsInfo,
                    dbProductQuantity,
                    strUpdateType);

                iICInventoryStockSerialID = objICInventoryStockSerialsController.UpdateObject(objICInventoryStockSerialsInfo);
            }
            else
            {
                objICInventoryStockSerialsInfo = new ICInventoryStockSerialsInfo();
                objICInventoryStockSerialsInfo.FK_ICStockID = iICStockID;
                objICInventoryStockSerialsInfo.FK_ICProductID = iICProductID;
                objICInventoryStockSerialsInfo.FK_ICInventoryStockID = iICInventoryStockID;
                objICInventoryStockSerialsInfo.ICInventoryStockSerialProductSerialNo = strICProductSerialNo;

                UpdateInventoryStockSerialQuantity(
                    objICInventoryStockSerialsInfo,
                    dbProductQuantity,
                    strUpdateType);
                iICInventoryStockSerialID = objICInventoryStockSerialsController.CreateObject(objICInventoryStockSerialsInfo);
            }
            return iICInventoryStockSerialID;
        }

        public static int UpdateInventoryStockSerials(int iICInventoryStockID, int iICProductID, int iICProductAttributeID,
                                            int iICStockID, int iICProductSerieID,
                                            double dbProductQuantity,
                                            String strUpdateType)
        {
            int iICInventoryStockSerialID = 0;
            ICInventoryStockSerialsController objICInventoryStockSerialsController = new ICInventoryStockSerialsController();
            ICInventoryStockSerialsInfo objICInventoryStockSerialsInfo = objICInventoryStockSerialsController.GetInventoryStockSerialByStockIDAndProductSerieID(iICStockID, iICProductSerieID);
            if (objICInventoryStockSerialsInfo != null)
            {
                UpdateInventoryStockSerialQuantity(
                    objICInventoryStockSerialsInfo,
                    dbProductQuantity,
                    strUpdateType);

                iICInventoryStockSerialID = objICInventoryStockSerialsController.UpdateObject(objICInventoryStockSerialsInfo);
            }
            else
            {
                objICInventoryStockSerialsInfo = new ICInventoryStockSerialsInfo();
                objICInventoryStockSerialsInfo.FK_ICInventoryStockID = iICInventoryStockID;
                objICInventoryStockSerialsInfo.FK_ICStockID = iICStockID;
                objICInventoryStockSerialsInfo.FK_ICProductID = iICProductID;
                objICInventoryStockSerialsInfo.FK_ICProductAttributeID = iICProductAttributeID;
                objICInventoryStockSerialsInfo.FK_ICProductSerieID = iICProductSerieID;

                UpdateInventoryStockSerialQuantity(
                    objICInventoryStockSerialsInfo,
                    dbProductQuantity,
                    strUpdateType);
                iICInventoryStockSerialID = objICInventoryStockSerialsController.CreateObject(objICInventoryStockSerialsInfo);
            }
            return iICInventoryStockSerialID;
        }

        public static int UpdateInventoryStockSlot(int iICInventoryStockID, int iICProductID,
                                            int iICStockSlotID,
                                            double dbProductQuantity,
                                            String strUpdateType)
        {
            int iICInventoryStockSlotID = 0;
            ICInventoryStockSlotsController objICInventoryStockSlotsController = new ICInventoryStockSlotsController();
            ICInventoryStockSlotsInfo objICInventoryStockSlotsInfo = objICInventoryStockSlotsController.GetICInventoryStockSlotByProductAndStockSlot(iICProductID, iICStockSlotID);
            if (objICInventoryStockSlotsInfo != null)
            {
                UpdateInventoryStockSlotQuantity(
                    objICInventoryStockSlotsInfo,
                    dbProductQuantity,                    
                    strUpdateType);

                iICInventoryStockSlotID = objICInventoryStockSlotsController.UpdateObject(objICInventoryStockSlotsInfo);
            }
            else
            {
                objICInventoryStockSlotsInfo = new ICInventoryStockSlotsInfo();
                objICInventoryStockSlotsInfo.FK_ICStockSlotID = iICStockSlotID;
                objICInventoryStockSlotsInfo.FK_ICProductID = iICProductID;
                objICInventoryStockSlotsInfo.FK_ICInventoryStockID = iICInventoryStockID;
                UpdateInventoryStockSlotQuantity(
                    objICInventoryStockSlotsInfo,
                    dbProductQuantity,                    
                    strUpdateType);
                iICInventoryStockSlotID = objICInventoryStockSlotsController.CreateObject(objICInventoryStockSlotsInfo);
            }
            return iICInventoryStockSlotID;
        }

        public static int UpdateInventoryStockSlot(int iICInventoryStockID, int iICProductID, int iICProductAttributeID,
                                            int iICStockSlotID,
                                            double dbProductQuantity,
                                            String strUpdateType)
        {
            int iICInventoryStockSlotID = 0;
            ICInventoryStockSlotsController objICInventoryStockSlotsController = new ICInventoryStockSlotsController();
            ICInventoryStockSlotsInfo objICInventoryStockSlotsInfo = objICInventoryStockSlotsController.GetInventoryStockSlotByStockSlotIDAndProductIDAndProductAttributeID(iICStockSlotID, iICProductID, iICProductAttributeID);
            if (objICInventoryStockSlotsInfo != null)
            {
                UpdateInventoryStockSlotQuantity(
                    objICInventoryStockSlotsInfo,
                    dbProductQuantity,
                    strUpdateType);

                iICInventoryStockSlotID = objICInventoryStockSlotsController.UpdateObject(objICInventoryStockSlotsInfo);
            }
            else
            {
                objICInventoryStockSlotsInfo = new ICInventoryStockSlotsInfo();
                objICInventoryStockSlotsInfo.FK_ICInventoryStockID = iICInventoryStockID;
                objICInventoryStockSlotsInfo.FK_ICStockSlotID = iICStockSlotID;
                objICInventoryStockSlotsInfo.FK_ICProductID = iICProductID;
                objICInventoryStockSlotsInfo.FK_ICProductAttributeID = iICProductAttributeID;
                UpdateInventoryStockSlotQuantity(
                    objICInventoryStockSlotsInfo,
                    dbProductQuantity,
                    strUpdateType);
                iICInventoryStockSlotID = objICInventoryStockSlotsController.CreateObject(objICInventoryStockSlotsInfo);
            }
            return iICInventoryStockSlotID;
        }
#if never
        public static void UpdateInventoryStockSlotSeries(int iICInventoryStockSlotID, int iMAProductID,
                                                    int iMAProductSerieID,
                                                    double dbMAProductSerieQuantity,                                        
                                                    String strUpdateType)
        {
            ICInventoryStockSlotSeriesController objICInventoryStockSlotSeriesController = new ICInventoryStockSlotSeriesController();
            ICInventoryStockSlotSeriesInfo objICInventoryStockSlotSeriesInfo = objICInventoryStockSlotSeriesController.GetICInventoryStockSlotSeriesByICInventoryStockSlotIDANdMAProductIDAndMAProductSerieID(
                                                                                                                        iICInventoryStockSlotID, iMAProductID, iMAProductSerieID);
            if (objICInventoryStockSlotSeriesInfo != null)
            {
                UpdateInventoryStockSlotSeriesQuantity(
                        objICInventoryStockSlotSeriesInfo,
                        dbMAProductSerieQuantity,                        
                        strUpdateType);

                objICInventoryStockSlotSeriesController.UpdateObject(objICInventoryStockSlotSeriesInfo);
            }
            else
            {
                objICInventoryStockSlotSeriesInfo = new ICInventoryStockSlotSeriesInfo();
                objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotID = iICInventoryStockSlotID;
                objICInventoryStockSlotSeriesInfo.MAProductID = iMAProductID;
                objICInventoryStockSlotSeriesInfo.MAProductSerieID = iMAProductSerieID;
                UpdateInventoryStockSlotSeriesQuantity(
                    objICInventoryStockSlotSeriesInfo,
                    dbMAProductSerieQuantity,                    
                    strUpdateType);
                objICInventoryStockSlotSeriesController.CreateObject(objICInventoryStockSlotSeriesInfo);
            }

        }


#endif

        private static void UpdateInventoryStockQuantity(
                                ICInventoryStocksInfo objICInventoryStocksInfo,
                                double dbProductQuantity,                                
                                String strUpdateType)
        {
            switch (strUpdateType)
            {
                case cstInventoryProposal:
                    {                        
                        objICInventoryStocksInfo.ICInventoryStockProposalQuantity += dbProductQuantity;
                        if (objICInventoryStocksInfo.ICInventoryStockProposalQuantity < 0)
                            objICInventoryStocksInfo.ICInventoryStockProposalQuantity = 0;
                        break;
                    }
                case cstInventoryPurchaseOrder:
                    {                        
                        objICInventoryStocksInfo.ICInventoryStockPurchaseOrderQuantity += dbProductQuantity;
                        if (objICInventoryStocksInfo.ICInventoryStockPurchaseOrderQuantity < 0)
                            objICInventoryStocksInfo.ICInventoryStockPurchaseOrderQuantity = 0;
                        break;
                    }
                case cstInventorySaleOrder:
                    {                        
                        objICInventoryStocksInfo.ICInventoryStockSaleOrderQuantity += dbProductQuantity;
                        if (objICInventoryStocksInfo.ICInventoryStockSaleOrderQuantity < 0)
                            objICInventoryStocksInfo.ICInventoryStockSaleOrderQuantity = 0;
                        break;
                    }
                case cstInventoryShipment:
                    {                        
                        objICInventoryStocksInfo.ICInventoryStockQuantity -= dbProductQuantity;                        
                        break;
                    }

                case cstInventoryReceipt:
                    {                        
                        objICInventoryStocksInfo.ICInventoryStockQuantity += dbProductQuantity;                        
                        break;
                    }
                case cstInventoryAdjust:
                    {
                        objICInventoryStocksInfo.ICInventoryStockQuantity = dbProductQuantity;
                        break;
                    }

            }
        }


        private static void UpdateInventoryStockSlotQuantity(
                                ICInventoryStockSlotsInfo objICInventoryStockSlotsInfo,
                                double dbProductQuantity,                                
                                String strUpdateType)
        {
            switch (strUpdateType)
            {
                case cstInventoryProposal:
                    {
                        
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotProposalQuantity += dbProductQuantity;
                        if (objICInventoryStockSlotsInfo.ICInventoryStockSlotProposalQuantity < 0)
                            objICInventoryStockSlotsInfo.ICInventoryStockSlotProposalQuantity = 0;
                        break;
                    }
                case cstInventoryPurchaseOrder:
                    {                        
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotPurchaseOrderQuantity += dbProductQuantity;
                        if (objICInventoryStockSlotsInfo.ICInventoryStockSlotPurchaseOrderQuantity < 0)
                            objICInventoryStockSlotsInfo.ICInventoryStockSlotPurchaseOrderQuantity = 0;
                        break;
                    }
                case cstInventorySaleOrder:
                    {                        
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotSaleOrderQuantity += dbProductQuantity;
                        if (objICInventoryStockSlotsInfo.ICInventoryStockSlotSaleOrderQuantity < 0)
                            objICInventoryStockSlotsInfo.ICInventoryStockSlotSaleOrderQuantity = 0;
                        break;
                    }
                case cstInventoryShipment:
                    {                        
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotQuantity -= dbProductQuantity;                        
                        break;
                    }

                case cstInventoryReceipt:
                    {                        
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotQuantity += dbProductQuantity;                        
                        break;
                    }
                case cstInventoryAdjust:
                    {
                        objICInventoryStockSlotsInfo.ICInventoryStockSlotQuantity = dbProductQuantity;
                        break;
                    }
            }
        }

        private static void UpdateInventoryStockSerialQuantity(
                                ICInventoryStockSerialsInfo objICInventoryStockSerialsInfo,
                                double dbProductQuantity,
                                String strUpdateType)
        {
            switch (strUpdateType)
            {
                case cstInventoryProposal:
                    {

                        objICInventoryStockSerialsInfo.ICInventoryStockSerialProposalQuantity += dbProductQuantity;
                        if (objICInventoryStockSerialsInfo.ICInventoryStockSerialProposalQuantity < 0)
                            objICInventoryStockSerialsInfo.ICInventoryStockSerialProposalQuantity = 0;
                        break;
                    }
                case cstInventoryPurchaseOrder:
                    {
                        objICInventoryStockSerialsInfo.ICInventoryStockSerialPurchaseOrderQuantity += dbProductQuantity;
                        if (objICInventoryStockSerialsInfo.ICInventoryStockSerialPurchaseOrderQuantity < 0)
                            objICInventoryStockSerialsInfo.ICInventoryStockSerialPurchaseOrderQuantity = 0;
                        break;
                    }
                case cstInventorySaleOrder:
                    {
                        objICInventoryStockSerialsInfo.ICInventoryStockSerialSaleOrderQuantity += dbProductQuantity;
                        if (objICInventoryStockSerialsInfo.ICInventoryStockSerialSaleOrderQuantity < 0)
                            objICInventoryStockSerialsInfo.ICInventoryStockSerialSaleOrderQuantity = 0;
                        break;
                    }
                case cstInventoryShipment:
                    {
                        objICInventoryStockSerialsInfo.ICInventoryStockSerialQuantity -= dbProductQuantity;
                        break;
                    }

                case cstInventoryReceipt:
                    {
                        objICInventoryStockSerialsInfo.ICInventoryStockSerialQuantity += dbProductQuantity;
                        break;
                    }
                case cstInventoryAdjust:
                    {
                        objICInventoryStockSerialsInfo.ICInventoryStockSerialQuantity = dbProductQuantity;
                        break;
                    }

            }
        }

#if never
        private static void UpdateInventoryStockSlotSeriesQuantity(
                                ICInventoryStockSlotSeriesInfo objICInventoryStockSlotSeriesInfo,
                                double dbMAProductSerieQuantity,                                
                                String strUpdateType)
        {
            switch (strUpdateType)
            {
                case cstInventoryReservedProposal:
                    {                        
                        objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieProposalQuantity += dbMAProductSerieQuantity;
                        if (objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieProposalQuantity < 0)
                            objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieProposalQuantity = 0;
                        break;
                    }
                case cstInventoryReservedPurchaseOrder:
                    {                        
                        objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSeriePurchaseOrderQuantity += dbMAProductSerieQuantity;
                        if (objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSeriePurchaseOrderQuantity < 0)
                            objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSeriePurchaseOrderQuantity = 0;
                        break;
                    }
                case cstInventoryReservedSaleOrder:
                    {                        
                        objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieSellOrderQuantity += dbMAProductSerieQuantity;
                        if (objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieSellOrderQuantity < 0)
                            objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieSellOrderQuantity = 0;
                        break;
                    }
                case cstInventoryShipment:
                    {                        
                        objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieQuantity -= dbMAProductSerieQuantity;                        
                        break;
                    }
                case cstInventoryReceipt:
                    {                       
                        objICInventoryStockSlotSeriesInfo.ICInventoryStockSlotSerieQuantity += dbMAProductSerieQuantity;                     
                        break;
                    }

            }
        }
#endif
        #endregion

        /// <summary>
        /// Get description for inventory status
        /// </summary>
        /// 
        public static String GetInventoryStatusMessage(TransactionUtil.InventoryStatus status)
        {
            switch (status)
            {
                case TransactionUtil.InventoryStatus.Empty:
                    return "Not enough";
                case TransactionUtil.InventoryStatus.LessThanMinQty:
                    return "Less than the minimum quantity";
                case TransactionUtil.InventoryStatus.GreaterThanMaxQty:
                    return "Greater than the maximum quantity";
                default:
                    return String.Empty;
            }
        }
    }
}
